﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ESRI
{
    public class FileHeader
    {
        public int FileCode { get; set; }
        public int[] Unused { get; set; }
        public int FileLength { get; set; }
        public int Version { get; set; }
        public ShapeType ShapeType { get; set; }
        public BoundingBox BoundingBox { get; set; }

        public FileHeader(byte[] fileHeader)
        {
            if (fileHeader.Length != 100) throw new ArgumentOutOfRangeException("fileHeader", fileHeader.Length, "The file header is exactly 100 bytes long anything less or more is unacceptable.");

            Unused = new int[6];
            byte[] fileCode = new byte[4];
            byte[] unused1 = new byte[4];
            byte[] unused2 = new byte[4];
            byte[] unused3 = new byte[4];
            byte[] unused4 = new byte[4];
            byte[] unused5 = new byte[4];
            byte[] fileLength = new byte[4];
            byte[] version = new byte[4];
            byte[] shapeType = new byte[4];
            byte[] xmin = new byte[8];
            byte[] ymin = new byte[8];
            byte[] xmax = new byte[8];
            byte[] ymax = new byte[8];
            byte[] zmin = new byte[8];
            byte[] zmax = new byte[8];
            byte[] mmin = new byte[8];
            byte[] mmax = new byte[8];

            LoadHeaderArrays(fileHeader, fileCode, unused1, unused2, unused3, unused4, unused5, fileLength, version, shapeType, xmin, ymin, xmax, ymax, zmin, zmax, mmin, mmax);
            LoadHeader(fileCode, unused1, unused2, unused3, unused4, unused5, fileLength, version, shapeType, xmin, ymin, xmax, ymax, zmin, zmax, mmin, mmax);
        }
        public FileHeader(byte[] fileCode, byte[] unused1, byte[] unused2, byte[] unused3, byte[] unused4, byte[] unused5, byte[] fileLength, byte[] version, byte[] shapeType, byte[] xmin, byte[] ymin, byte[] xmax, byte[] ymax, byte[] zmin, byte[] zmax, byte[] mmin, byte[] mmax)
        {
            LoadHeader(fileCode, unused1, unused2, unused3, unused4, unused5, fileLength, version, shapeType, xmin, ymin, xmax, ymax, zmin, zmax, mmin, mmax);
        }
        public FileHeader(int fileCode, int unused1, int unused2, int unused3, int unused4, int unused5, int fileLength, int version, int shapeType, double xmin, double ymin, double xmax, double ymax, double zmin, double zmax, double mmin, double mmax)
        {
            FileCode = fileCode;
            Unused[1] = unused1;
            Unused[2] = unused2;
            Unused[3] = unused3;
            Unused[4] = unused4;
            Unused[5] = unused5;
            FileLength = fileLength;
            Version = version;
            ShapeType = (ShapeType)shapeType;
            BoundingBox.MMax = mmax;
            BoundingBox.MMin = mmin;
            BoundingBox.XMax = xmax;
            BoundingBox.XMin = xmin;
            BoundingBox.YMax = ymax;
            BoundingBox.YMin = ymin;
            BoundingBox.ZMax = zmax;
            BoundingBox.ZMin = zmin;
        }
        private void LoadHeader(byte[] fileCode, byte[] unused1, byte[] unused2, byte[] unused3, byte[] unused4, byte[] unused5, byte[] fileLength, byte[] version, byte[] shapeType, byte[] xmin, byte[] ymin, byte[] xmax, byte[] ymax, byte[] zmin, byte[] zmax, byte[] mmin, byte[] mmax)
        {
            Unused = new int[6];
            Array.Reverse(fileCode);
            FileCode = BitConverter.ToInt32(fileCode, 0);
            Array.Reverse(unused1);
            Unused[1] = BitConverter.ToInt32(unused1, 0);
            Array.Reverse(unused2);
            Unused[2] = BitConverter.ToInt32(unused2, 0);
            Array.Reverse(unused3);
            Unused[3] = BitConverter.ToInt32(unused3, 0);
            Array.Reverse(unused4);
            Unused[4] = BitConverter.ToInt32(unused4, 0);
            Array.Reverse(unused5);
            Unused[5] = BitConverter.ToInt32(unused5, 0);
            Array.Reverse(fileLength);
            FileLength = BitConverter.ToInt32(fileLength, 0);
            Version = BitConverter.ToInt32(version, 0);
            ShapeType = (ShapeType)BitConverter.ToInt32(shapeType, 0);
            BoundingBox.XMin = BitConverter.ToDouble(xmin, 0);
            BoundingBox.YMin = BitConverter.ToDouble(ymin, 0);
            BoundingBox.XMax = BitConverter.ToDouble(xmax, 0);
            BoundingBox.YMax = BitConverter.ToDouble(ymax, 0);
            BoundingBox.ZMin = BitConverter.ToDouble(zmin, 0);
            BoundingBox.ZMax = BitConverter.ToDouble(zmax, 0);
            BoundingBox.MMin = BitConverter.ToDouble(mmin, 0);
            BoundingBox.MMax = BitConverter.ToDouble(mmax, 0);
        }
        private static void LoadHeaderArrays(byte[] fileHeader, byte[] fileCode, byte[] unused1, byte[] unused2, byte[] unused3, byte[] unused4, byte[] unused5, byte[] fileLength, byte[] version, byte[] shapeType, byte[] xmin, byte[] ymin, byte[] xmax, byte[] ymax, byte[] zmin, byte[] zmax, byte[] mmin, byte[] mmax)
        {
            int pos = 0;
            for (int x = 1; x <= 4; x++)
            {
                fileCode[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 4; x++)
            {
                unused1[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 4; x++)
            {
                unused2[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 4; x++)
            {
                unused3[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 4; x++)
            {
                unused4[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 4; x++)
            {
                unused5[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 4; x++)
            {
                fileLength[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 4; x++)
            {
                version[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 4; x++)
            {
                shapeType[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 8; x++)
            {
                xmin[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 8; x++)
            {
                ymin[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 8; x++)
            {
                xmax[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 8; x++)
            {
                ymax[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 8; x++)
            {
                zmin[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 8; x++)
            {
                zmax[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 8; x++)
            {
                mmin[x] = fileHeader[pos];
                pos++;
            }
            for (int x = 1; x <= 8; x++)
            {
                mmax[x] = fileHeader[pos];
                pos++;
            }
        }
    }
}
